package com.gexiaobao.pigeon.ui.fragment.mine.organization

import android.annotation.SuppressLint
import android.os.Bundle
import android.text.TextUtils
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import com.gexiaobao.pigeon.R
import com.gexiaobao.pigeon.app.base.BaseFragment
import com.gexiaobao.pigeon.app.ext.Constant
import com.gexiaobao.pigeon.app.ext.init
import com.gexiaobao.pigeon.app.model.UIMessageEntity
import com.gexiaobao.pigeon.app.network.HttpUtil
import com.gexiaobao.pigeon.app.util.KvUtils
import com.gexiaobao.pigeon.app.util.RxToast
import com.gexiaobao.pigeon.app.util.SoftKeyBoardListener
import com.gexiaobao.pigeon.app.util.SoftKeyBoardListener.OnSoftKeyBoardChangeListener
import com.gexiaobao.pigeon.app.weight.recycleview.SpaceItemDecoration
import com.gexiaobao.pigeon.databinding.FragmentInteractionChatBinding
import com.gexiaobao.pigeon.ui.adapter.ChatLiveMessageAdapter
import com.gexiaobao.pigeon.ui.adapter.EmotionsAdapter
import com.gexiaobao.pigeon.viewmodel.OrgDetailViewModel
import com.luck.picture.lib.thread.PictureThreadUtils.runOnUiThread
import com.xinbida.wukongim.WKIM
import com.xinbida.wukongim.entity.WKChannelType
import com.xinbida.wukongim.entity.WKMsg
import com.xinbida.wukongim.interfaces.IGetSocketIpAndPortListener
import com.xinbida.wukongim.message.type.WKConnectStatus
import com.xinbida.wukongim.msgmodel.WKTextContent
import me.hgj.jetpackmvvm.ext.util.setOnclickNoRepeat
import me.hgj.jetpackmvvm.util.LogUtils
import org.json.JSONException
import org.json.JSONObject

/**
 * @Author      : hxw
 * @Date        : 2024/11/18 18:06
 * @Describe    : 直播互动（im）
 */
class FragmentInteractionChat : BaseFragment<OrgDetailViewModel, FragmentInteractionChatBinding>() {

    private var mOrgId = 0
    private var mRaceId = 0
    private var mRaceName = ""

    private val adapter: ChatLiveMessageAdapter by lazy { ChatLiveMessageAdapter() }
    private val eMojAdapter: EmotionsAdapter by lazy { EmotionsAdapter(arrayListOf()) }
    private var channelID = ""
    private var mChannelType: Byte = 0
    private var mLoginUID = ""
    private var mUid = ""
    private var token = ""
    private val emojiChar =
        arrayOf(
            "😀", "😃", "😄", "😁", "😆", "😅", "🤣", "😂", "🙂", "🙃", "😉", "😊", "😇", "🥰", "😍", "🤩", "😘", "😗", "😚", "😙",
            "😋", "😛", "😜", "🤪", "😝", "🤑", "🤗", "🤭", "🤫", "🤔", "🤐", "🤨", "😐", "😑", "😶", "😏", "😒", "🙄", "😬", "🤥", "😶‍",
            "😮‍", "😌", "😔", "😪", "🤤", "😴", "😷", "🤒", "🤕", "🤢", "🤮", "🤧", "🥵", "🥶", "🥴", "😵", "🤯", "😵‍", "🤠", "🥳", "😎",
            "🤓", "🧐", "😕", "😟", "🙁", "☹", "😮", "😯", "😲", "😳", "🥺", "😦", "😧", "😨", "😰", "😥", "😢", "😭", "😱", "😖", "😣",
            "😞", "😓", "😩", "😫", "🥱", "😤", "😡", "😠", "🤬", "😈", "👿", "💀", "☠", "💩", "🤡", "🙈", "🙉", "🙊", "💋", "💔", "❤"
        )

    @SuppressLint("SetTextI18n")
    override fun initView(savedInstanceState: Bundle?) {
        mRaceName = requireArguments().getString("raceName").toString()

        mOrgId = requireArguments().getInt("orgId", 0)
        mRaceId = requireArguments().getInt("raceId", 0)
        token = requireArguments().getString("token").toString()
        mLoginUID = KvUtils.decodeString(Constant.USERID)
        WKIM.getInstance().init(requireContext(), mLoginUID, token)
        channelID = requireArguments().getString("channelId").toString()
        mUid = requireArguments().getString("uid").toString()
        mChannelType = WKChannelType.GROUP//群聊

        /** 初始化聊天内容的recyclerview */
        mDatabind.recycleView.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
        mDatabind.recycleView.adapter = adapter

        /** 初始化表情符号的recyclerview */
        mDatabind.panelView.recyclerviewEmoticons.init(GridLayoutManager(requireContext(), 6), eMojAdapter).addItemDecoration(
            SpaceItemDecoration(0, 0)
        )
        val list: ArrayList<String> = emojiChar.toList() as ArrayList<String>
        eMojAdapter.setList(list)

        eMojAdapter.setOnItemClickListener { _, _, position ->
            mDatabind.chatInputEt.setText(mDatabind.chatInputEt.text.toString() + eMojAdapter.data[position])
            mDatabind.chatInputEt.setSelection(mDatabind.chatInputEt.length())
        }
        onChatListeners()
        showLoading(getString(R.string.loading))
        getHistoryMessages()

        mDatabind.swipeRefreshLayout.init {
            getHistoryMessages()
        }

        /**
         * 显示软键盘  隐藏删除
         */
        SoftKeyBoardListener.setListener(requireActivity(), object : OnSoftKeyBoardChangeListener {
            override fun keyBoardShow(height: Int) {
                /** 键盘弹出 */
                if (adapter.data.isNotEmpty()) {
                    mDatabind.recycleView.smoothScrollToPosition(adapter.itemCount - 1)
                }
            }

            override fun keyBoardHide(height: Int) {
                /** 键盘隐藏 */
            }
        })
    }

    @SuppressLint("NotifyDataSetChanged")
    private fun getHistoryMessages() {
        Thread {
            HttpUtil.getInstance().getHistoryMsg(mLoginUID, channelID, mChannelType) { list ->
                if (mDatabind.swipeRefreshLayout.isRefreshing) {
                    mDatabind.swipeRefreshLayout.isRefreshing = false
                }
                dismissLoading()
                if (list != null && list.size > 0) {
                    runOnUiThread {
                        adapter.setList(list)
                        mDatabind.recycleView.scrollToPosition(adapter.data.size - 1)
                    }
                } else {
                    adapter.setList(ArrayList())
                }
            }
        }.start()
    }

    @SuppressLint("NotifyDataSetChanged")
    private fun onChatListeners() {
        /** 连接状态监听 */
        WKIM.getInstance().connectionManager.addOnConnectionStatusListener("live_connect") { code: Int, _: String? ->
            when (code) {
                WKConnectStatus.success -> LogUtils.debugInfo("连接成功")
                WKConnectStatus.fail -> LogUtils.debugInfo("连接失败")
                WKConnectStatus.connecting -> LogUtils.debugInfo("连接中...")
                WKConnectStatus.noNetwork -> LogUtils.debugInfo("无网络")
                WKConnectStatus.kicked -> LogUtils.debugInfo("被踢")
            }
        }

        /** 发送消息回执 */
        WKIM.getInstance().msgManager.addOnSendMsgAckListener("ack_key") { msg: WKMsg ->
            var i = 0
            val size = adapter.data.size
            while (i < size) {
                if (adapter.data[i].msg.clientSeq == msg.clientSeq) {
                    adapter.data[i].msg.status = msg.status
                    adapter.notifyItemChanged(i)
                    break
                }
                i++
            }
        }

        /** 新消息监听 */
        WKIM.getInstance().msgManager.addOnNewMsgListener("newMessage") { msgList: List<WKMsg?> ->
            for (msg in msgList) {
                adapter.addData(UIMessageEntity(msg!!, 0))
            }
        }

        /** 监听发送消息入库返回 */
        WKIM.getInstance().msgManager.addOnSendMsgCallback("insert_msg") { msg: WKMsg? ->
            adapter.addData(UIMessageEntity(msg!!, 1))
            adapter.notifyDataSetChanged()
        }

        /** 长连接地址获取 */
        WKIM.getInstance().connectionManager.addOnGetIpAndPortListener { andPortListener: IGetSocketIpAndPortListener ->
            Thread {
                HttpUtil.getInstance()["/route", { code: Int, data: String ->
                    if (code == 200) {
                        try {
                            val jsonObject = JSONObject(data)
                            val tcpAddress = jsonObject.optString("tcp_addr")
                            val strings = tcpAddress.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
                            andPortListener.onGetSocketIpAndPort(strings[0], strings[1].toInt())
                        } catch (e: JSONException) {
                            throw RuntimeException(e)
                        }
                    }
                }]
            }.start()
        }
    }

    override fun onBindViewClick() {
        super.onBindViewClick()
        setOnclickNoRepeat(mDatabind.sendMsgTv) {
            when (it) {
                mDatabind.sendMsgTv -> sendChatMsg()
            }
        }
    }

    private fun sendChatMsg() {
        val content = mDatabind.chatInputEt.text.toString()
        if (TextUtils.isEmpty(channelID)) {
            RxToast.showToast(getString(R.string.input_channel_id))
            return
        }
        if (TextUtils.isEmpty(content)) {
            RxToast.showToast(getString(R.string.input_content))
            return
        }

        WKIM.getInstance().msgManager.sendMessage(WKTextContent(content), channelID, mChannelType)
        mDatabind.chatInputEt.setText("")
        mDatabind.recycleView.smoothScrollToPosition(adapter.getItemCount() - 1)
    }

    override fun onResume() {
        super.onResume()
        /** 连接 */
        WKIM.getInstance().connectionManager.connection()
    }

    override fun onStop() {
        super.onStop()
        WKIM.getInstance().connectionManager.disconnect(false)
    }

    override fun onDestroy() {
        super.onDestroy()
        // 断开连接
        WKIM.getInstance().connectionManager.disconnect(true)
        // 取消监听
        WKIM.getInstance().msgManager.removeNewMsgListener("newMessage")
        WKIM.getInstance().msgManager.removeSendMsgCallBack("insert_msg")
        WKIM.getInstance().msgManager.removeSendMsgAckListener("ack_key")
        WKIM.getInstance().connectionManager.removeOnConnectionStatusListener("live_connect")
    }

    companion object {
        fun newInstance(orgId: Int, raceId: Int, token: String, channelId: String, uid: String): FragmentInteractionChat {
            val fragment = FragmentInteractionChat()
            val bundle = Bundle()
            bundle.putInt("raceId", raceId)
            bundle.putInt("orgId", orgId)
            bundle.putString("token", token)
            bundle.putString("channelId", channelId)
            bundle.putString("channelId", channelId)
            bundle.putString("uid", uid)
            fragment.arguments = bundle
            return fragment
        }
    }

}